package com.dynamic.mybatis.core.utils;

import com.sun.org.apache.xml.internal.serialize.OutputFormat;
import com.sun.org.apache.xml.internal.serialize.XMLSerializer;
import org.w3c.dom.DOMConfiguration;
import org.w3c.dom.Document;
import org.w3c.dom.bootstrap.DOMImplementationRegistry;
import org.w3c.dom.ls.DOMImplementationLS;
import org.w3c.dom.ls.LSOutput;
import org.w3c.dom.ls.LSSerializer;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringWriter;

/**
 * @Description
 * @Author xs
 * @Date 2023/4/17 10:25
 */
public class XmlUtil {


    public static String javaApacheFormatPretty(String xml) {
        OutputFormat format = new OutputFormat();
        format.setIndenting(true);
        format.setIndent(2);
        format.setOmitXMLDeclaration(true);
        format.setLineWidth(120);
        //format.setLineWidth(OutputFormat.Defaults.LineWidth);
        StringWriter writer = new StringWriter();
        XMLSerializer serializer = new XMLSerializer(writer, format);
        ByteArrayInputStream bis = new ByteArrayInputStream(xml.getBytes());
        try {
            Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(bis);
            serializer.serialize(document.getDocumentElement());
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            try {
                bis.close();
                writer.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        return writer.toString();
    }


    public static String formatPretty(String xml) {
        String subscrXML=null;
        DOMImplementationRegistry registry = null;
        DOMImplementationLS impls = null;
        LSOutput domOutput = null;
        LSSerializer domWriter = null;
        try (
                InputStream inputStream = new ByteArrayInputStream(xml.getBytes());
                StringWriter stringWriter = new StringWriter();
            ){
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = factory.newDocumentBuilder();
            Document doc =   builder.parse(inputStream,null);

            registry =  DOMImplementationRegistry.newInstance();
            impls =  (DOMImplementationLS)registry.getDOMImplementation("LS");
            //Prepare the output
            domOutput = impls.createLSOutput();
            domOutput.setEncoding(java.nio.charset.Charset.defaultCharset().name());
            domOutput.setCharacterStream(stringWriter);
            domOutput.setEncoding("UTF-8");
            //Prepare the serializer
            domWriter = impls.createLSSerializer();
            DOMConfiguration domConfig = domWriter.getDomConfig();
            domConfig.setParameter("format-pretty-print", true);
            domConfig.setParameter("element-content-whitespace", true);
            domWriter.setNewLine("\r\n");
            domConfig.setParameter("cdata-sections", Boolean.TRUE);

            //And finaly, write
            domWriter.write(doc, domOutput);
            subscrXML = domOutput.getCharacterStream().toString();
            System.out.println(subscrXML);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return subscrXML;
    }

    public static void main(String[] args) {
        String xml = "<select id=\"selectByIdTest\" name=\"查询测试\" parameterType=\"map\" resultType=\"map\" returnType=\"map\">\n" +
                "  SELECT id,id AS id,user_account AS userAccount,name AS name,password AS password,status AS status,birthday AS birthday,work_begin_time AS workBeginTime,work_end_time AS workEndTime,is_deleted AS isDeleted,create_time AS createTime,create_by AS createBy,update_time AS updateTime,update_by AS updateBy FROM test WHERE id=#{id} \n" +
                "</select>\n";


        System.out.print(formatPretty(xml));
    }
}